package platformer;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

import platformer.view.sprites.AnimatedSprite;
import platformer.view.sprites.states.*;

class ImageCanvas extends JPanel implements KeyListener{

    /**
	 * 
	 */
	private static final long serialVersionUID = 1920732339290116642L;
	
	class AnimatedSpriteList{
		
		List<AnimatedSprite> AnimatedSpriteList = new ArrayList<AnimatedSprite>();
		
		public void add(AnimatedSprite sprite) {
			AnimatedSpriteList.add( sprite );
		}
		
		public void setToIdle() {			
			for( AnimatedSprite sprite : this.AnimatedSpriteList ) {
				sprite.setToIdle();
			}
		}
		
		public void setAnimationSate(AnimationState state) {
			for( AnimatedSprite sprite : this.AnimatedSpriteList ) {
				sprite.setAnimationSate(state);
			}
		}
		
		public List<AnimatedSprite> getList(){
			return AnimatedSpriteList;
		}
		
	}
	
	AnimatedSpriteList animatedSpriteList = new AnimatedSpriteList();
	
	boolean[] keys = new boolean[526];
	
	static enum State {
		Idle, Walking, Running, Flying, Attacking
	}
	
	State animationState = State.Walking;
	
	long lastKeyPress = System.currentTimeMillis();
	int lastKey=0;
	final static int TIME_MAX = 200;
	final static int TIME_MIN = 100;
	
	static String imagesFolder = "img/";
	
    public ImageCanvas( int height, int width ) {
    	setFocusable(true);  // so that can receive key-events
		requestFocus();
		addKeyListener(this);
		animatedSpriteList.add(new AnimatedSprite(imagesFolder+"derpy.png"));
		animatedSpriteList.add(new AnimatedSprite(imagesFolder+"fluttershy.png"));
		animatedSpriteList.add(new AnimatedSprite(imagesFolder+"rainbowdash.png"));
		animatedSpriteList.add(new AnimatedSprite(imagesFolder+"rarity.png"));
		animatedSpriteList.add(new AnimatedSprite(imagesFolder+"trixie.png"));
		animatedSpriteList.add(new AnimatedSprite(imagesFolder+"octavia.png"));/**/
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        setBackground( Color.BLACK );
        int i = 0;
        for( AnimatedSprite sprite : animatedSpriteList.getList() ) {
            g.drawImage(sprite.getNextFrame(), i*96, 0, null);
            i++;
		}
    }

	@Override
	public void keyPressed(KeyEvent e)
	{
		keys[e.getKeyCode()] = true;
		
		switch (e.getKeyCode()) {
			case KeyEvent.VK_UP:
				upPressed();
				break;
			case KeyEvent.VK_DOWN:
				downPressed();
				break;
			case KeyEvent.VK_LEFT:
				leftPressed();
				break;
			case KeyEvent.VK_RIGHT:
				rightPressed();
				break;
			case KeyEvent.VK_SPACE:
				spacePressed();
				break;
		}
		
		lastKeyPress = System.currentTimeMillis();
        lastKey = e.getKeyCode();
		
	}
	
	private void upPressed() {
		
		if(keys[KeyEvent.VK_RIGHT] == true){
			animationState = State.Flying;
			animatedSpriteList.setAnimationSate( new FlyingRight() );
			return;
		}
		else if(keys[KeyEvent.VK_LEFT] == true) {
			animationState = State.Flying;
			animatedSpriteList.setAnimationSate( new FlyingLeft() );
			return;
		}
		
		animationState = State.Flying;
		animatedSpriteList.setAnimationSate( new FlyingDown().getIdle() );
		
	}
	
	private void downPressed() {
		
		
		if(keys[KeyEvent.VK_RIGHT] == true){
			animationState = State.Walking;
			animatedSpriteList.setAnimationSate( new WalkingRight() );
			return;
		}
		else if(keys[KeyEvent.VK_LEFT] == true) {
			animationState = State.Walking;
			animatedSpriteList.setAnimationSate( new WalkingLeft() );
			return;
		}
		
		animationState = State.Walking;
		animatedSpriteList.setAnimationSate( new WalkingDown().getIdle() );

	}
	
	private void leftPressed() {
		
		if(animationState == State.Running) return;

		if (	System.currentTimeMillis() - lastKeyPress < TIME_MAX 	&& 
				System.currentTimeMillis() - lastKeyPress > TIME_MIN 	&& 
				(lastKey==KeyEvent.VK_LEFT)
			){
			animationState = State.Running;
			animatedSpriteList.setAnimationSate( new RunningLeft() );     
			return;
		}
		
		keys[KeyEvent.VK_RIGHT] = false;
		
		if(keys[KeyEvent.VK_UP] == true){
			animationState = State.Flying;
			animatedSpriteList.setAnimationSate( new FlyingLeft() );
			return;
		}
		else if(keys[KeyEvent.VK_DOWN] == true) {
			animationState = State.Walking;
			animatedSpriteList.setAnimationSate( new WalkingLeft() );
			return;
		}
		
		if(animationState == State.Walking )
			animatedSpriteList.setAnimationSate( new WalkingLeft() );
		else if( animationState == State.Flying )
			animatedSpriteList.setAnimationSate( new FlyingLeft() );
	}
	
	private void rightPressed() {		
		
		if(animationState == State.Running) return;
		
		if (System.currentTimeMillis() - lastKeyPress < TIME_MAX && System.currentTimeMillis() - lastKeyPress > TIME_MIN && (lastKey==KeyEvent.VK_RIGHT)){
			animationState = State.Running;
			animatedSpriteList.setAnimationSate( new RunningRight() );     
			return;
		}
		
		keys[KeyEvent.VK_LEFT] = false;
		
		if(keys[KeyEvent.VK_UP] == true){
			animationState = State.Flying;
			animatedSpriteList.setAnimationSate( new FlyingRight() );
			return;
		}
		else if(keys[KeyEvent.VK_DOWN] == true) {
			animationState = State.Walking;
			animatedSpriteList.setAnimationSate( new WalkingRight() );
			return;
		}
		
		if(animationState == State.Walking )
			animatedSpriteList.setAnimationSate( new WalkingRight() );
		else if( animationState == State.Flying )
			animatedSpriteList.setAnimationSate( new FlyingRight() );
	}
	
	private void spacePressed() {	
		animatedSpriteList.setAnimationSate( new AttackRight() );
	}
	
	private boolean noKeyPressed() {
		return !( keys[KeyEvent.VK_RIGHT] || keys[KeyEvent.VK_DOWN] || keys[KeyEvent.VK_LEFT] || keys[KeyEvent.VK_UP]);
	}

	@Override
	public void keyReleased(KeyEvent e){
		keys[e.getKeyCode()] = false;
		if(noKeyPressed()) {
			animatedSpriteList.setToIdle();
			if(!(animationState == State.Flying))animationState = State.Walking;
		}
			
	}

	@Override
	public void keyTyped(KeyEvent e){
	}

}
